#!/usr/bin/env python
# -*- coding: utf-8 -*-
# datetime: 15/4/2023 下午10:52
# Author: name
# File: data_extract.py
# ide: PyCharm
# description:

"""
    数据提取
        正则数据提取
        jmespath数据提取
        jsonpath数据提取
"""
import json
import re

import jmespath
import jsonpath
from pywebio.output import *
from pywebio.pin import put_input, put_textarea, pin_update, pin
from pywebio.session import eval_js

from commons.comms import error_toast
from frontend.menus import show_menus


def json_formate(textarea_name, action):
    json_data = pin[textarea_name]
    # print(json_data)
    # print(type(json_data))
    if action == "formate":
        try:
            formatted_json = json.dumps(json.loads(json_data), indent=4, sort_keys=True, ensure_ascii=False)
            # print(formatted_json)
            pin_update(textarea_name, value=formatted_json)
        except:
            error_toast("数据格式化异常")
            return
    if action == "compress":
        try:
            compressed_json = json.dumps(json.loads(json_data), separators=(",", ":"), ensure_ascii=False)
            # print(compressed_json)
            pin_update(textarea_name, value=compressed_json)
        except:
            error_toast("数据格式化异常")
            return


def data_extract(mode, express_name, source_textarea_name, result_textarea_name):
    source_data = pin[source_textarea_name]
    if mode == "jmespath":
        try:
            jmespath_express = pin[express_name]
            extract_result = jmespath.search(jmespath_express, json.loads(source_data))
            extract_result = json.dumps(extract_result, indent=4, sort_keys=True, ensure_ascii=False)
            # print(extract_result)
            pin_update(result_textarea_name, value=extract_result)
        except:
            error_toast("jmespath数据提取失败")
            return
    if mode == "jsonpath":
        try:
            jsonpath_express = pin[express_name]
            extract_result = jsonpath.jsonpath(json.loads(source_data), jsonpath_express)
            extract_result = json.dumps(extract_result, indent=4, sort_keys=True, ensure_ascii=False)
            # print(extract_result)
            pin_update(result_textarea_name, value=extract_result)
        except:
            error_toast("jsonpath数据提取失败")
            return
    if mode == "re":
        try:
            print(source_data)
            extract_result = re.findall(pin[express_name], source_data)
            extract_result = json.dumps(extract_result, indent=4, sort_keys=True, ensure_ascii=False)
            # print(extract_result)
            pin_update(result_textarea_name, value=extract_result)
        except:
            error_toast("正则数据提取失败")
            return


def html_show_data_extract():
    """
    数据提取

    :return:
    """
    show_menus()
    put_tabs([
        {
            "title": "jmespath",
            "content": [
                put_text("请输入jmespath表达式:"),
                put_row(
                    [
                        put_input("jms_expression"),
                        None,
                        put_button("jmespath官方文档", onclick=lambda: eval_js(
                            'window.open("https://jmespath.org/tutorial.html")'))
                    ], size="48% 4% 48%"
                ),
                put_row(
                    [
                        put_text("请输入json数据:"),
                        put_text("提取结果:")
                    ], size="52% 48%"
                ),
                put_row(
                    [
                        put_button("提取",
                                   onclick=lambda: data_extract("jmespath", "jms_expression", "jms_json_data",
                                                                "jms_result")),
                        put_button("格式化",
                                   onclick=lambda: json_formate("jms_json_data", "formate"),
                                   small=True,
                                   color="info"),
                        None,
                        put_button("压缩",
                                   onclick=lambda: json_formate("jms_json_data", "compress"),
                                   small=True,
                                   color="info"),
                    ], size="10% 4% 0.5% 4%"
                ),
                put_row(
                    [
                        put_textarea("jms_json_data", rows=30, code={
                            "mode": "json",
                            'theme': 'darcula'
                        }),
                        None,
                        put_textarea("jms_result", rows=30, code={
                            "mode": "json",
                            'theme': 'darcula'
                        }),
                    ], size="800px 4% 800px"
                )
            ]
        },
        {
            "title": "jsonpath",
            "content": [
                put_text("请输入jsonpath表达式:"),
                put_row(
                    [
                        put_input("jsonpath_expression"),
                        None,
                        put_button("jsonpath官方文档", onclick=lambda: eval_js(
                            'window.open("https://github.com/json-path/JsonPath")')),
                    ], size="48% 4% 48%"
                ),
                put_row(
                    [
                        put_text("请输入json数据:"),
                        put_text("提取结果:")
                    ], size="52% 48%"
                ),
                put_row(
                    [
                        put_button("提取", onclick=lambda: data_extract("jsonpath", "jsonpath_expression",
                                                                        "jsonpath_json_data",
                                                                        "jsonpath_result")),
                        put_button("格式化",
                                   onclick=lambda: json_formate("jsonpath_json_data",
                                                                "formate"),
                                   small=True,
                                   color="info"),
                        None,
                        put_button("压缩",
                                   onclick=lambda: json_formate("jsonpath_json_data",
                                                                "compress"),
                                   small=True,
                                   color="info"),
                    ], size="10% 4% 0.5% 4%"
                ),
                put_row(
                    [
                        put_textarea("jsonpath_json_data", rows=30, code={
                            "mode": "json",
                            'theme': 'darcula'
                        }),
                        None,
                        put_textarea("jsonpath_result", rows=30, code={
                            "mode": "json",
                            'theme': 'darcula'
                        }),
                    ], size="800px 4% 800px"
                )
            ]
        },
        {
            "title": "re提取",
            "content": [
                put_text("请输入正则表达式:"),
                put_row(
                    [
                        put_input("re_expression"),
                        None,
                        put_button("re参考文档", onclick=lambda: eval_js(
                            'window.open("https://www.runoob.com/python3/python3-reg-expressions.html")')),
                    ], size="48% 4% 48%"
                ),
                put_row(
                    [
                        put_text("请输入文本数据:"),
                        put_text("提取结果:")
                    ], size="52% 48%"
                ),
                put_button("提取", onclick=lambda: data_extract("re", "re_expression", "re_data", "re_result")),
                put_row(
                    [
                        put_textarea("re_data", rows=30, code={
                            "mode": "text",
                            'theme': 'darcula'
                        }),
                        None,
                        put_textarea("re_result", rows=30, code={
                            "mode": "json",
                            'theme': 'darcula'
                        }),
                    ], size="800px 4% 800px"
                )
            ]
        }
    ], scope="data_list")
